package com.ruoyi.business.jisuController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.SaveType;
import com.ruoyi.common.utils.EncrypDES;
import com.ruoyi.common.utils.GetUrlParam;
import com.ruoyi.common.utils.OtherUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.framework.web.domain.server.Sys;
import com.ruoyi.system.domain.vo.R;
import com.ruoyi.system.protocol.IDynamicSearchService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.Assert;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.*;

@RestController
@RequestMapping("ownJSApi")
public class JiShuController {

    @Autowired
    private IDynamicSearchService dynamicSearchService;

    @Autowired
    private RedisCache redisCache;

    private final static String CLASSESEN = "jisukeji";

    private final static String OP_CLASSESEN = "op_ocpx";

    private final static String CALLBACK_URLBASE = "http://c2.wkanx.com/tracking";







    @Log(title = "极速科技", businessType = BusinessType.ESCALATION, esIndex = "jisu_log", saveType = SaveType.ES)
    @RequestMapping("/send")
    public Object send(HttpServletRequest request) throws Exception {
        String queryString = request.getQueryString();
        String channelId = request.getParameter("channelId");
        String dmpid = request.getParameter("dmpid");
        if(StringUtils.isBlank(channelId) || "null".equals(channelId)){
            return R.failure().msg("channelId不能为空");
        }
        if(StringUtils.isBlank(dmpid) || "null".equals(dmpid)){
            return R.failure().msg("dmpid不能为空");
        }

        Map<String, Object> baseParamsMap = GetUrlParam.queryStrToMap(queryString);
        for(String key: baseParamsMap.keySet()){
            if("android_id_md5".equals(key) || "oaid_md5".equals(key) || "oaid".equals(key)){
                if(StringUtils.isBlank(baseParamsMap.get(key)+"" ) || "null".equals(baseParamsMap.get(key)+"")){
                    baseParamsMap.put(key, "null");
                }
            }
        }

        baseParamsMap.remove("channelId");
        baseParamsMap.remove("dmpid");

        Map<String, Object> channelDetail = redisCache.getCacheMapValue(CLASSESEN+"Cache", channelId);
        if(channelDetail == null){
            return R.failure().msg("channelId不正确");
        }
        String url = channelDetail.get("request_address") + "";
        String requestType = channelDetail.get("request_type") + "";
        String requestAddress = GetUrlParam.getRequestAddress(url);
        String staticParameters = GetUrlParam.TruncateUrlPage(url);
        Map<String, Object> staticParamsMap = GetUrlParam.queryStrToMap(staticParameters);
        baseParamsMap.putAll(staticParamsMap);


        String ua = baseParamsMap.get("ua") + "";
        String ip = baseParamsMap.get("ip") + "";
        if(StringUtils.isNotBlank(ua) && !"null".equals(ua)){
            ua = URLDecoder.decode(ua, Constants.UTF8);
        }else{
            ua = null;
        }
        if(StringUtils.isNotBlank(ip) && !"null".equals(ip)){
        }else{
            ip = null;
        }

        String callbackClientId = channelDetail.get("callback_clientid") + "";
        String callbackSecretkey = channelDetail.get("callback_secretkey") + "";


        LinkedHashMap<String, String> callbackMap = new LinkedHashMap<>();
        callbackMap.put("cid", getMapValue(baseParamsMap, "cid"));
        callbackMap.put("clientid", callbackClientId);
        callbackMap.put("event_type", "1");
        callbackMap.put("idfa", getMapValue(baseParamsMap, "idfa"));
        //下游没有imei, 但是有imei_md5
        callbackMap.put("imei", getMapValue(baseParamsMap, "imei_md5"));
        //下游的mac是进行MD5加密过的就是上游的mac_md5
        callbackMap.put("mac", getMapValue(baseParamsMap, "mac_md5"));
        //因为两方字典值不同需要做一些替换
        String os = getMapValue(baseParamsMap, "os");
        callbackMap.put("os", "2".equals(os)?"0":"1".equals(os)?"1":os);
        //sid是下游给的click_id。 代表请求标识
        callbackMap.put("sid", getMapValue(baseParamsMap, "click_id"));
        //stime为上报时间戳。 上传过来的参数为ts
        callbackMap.put("stime", getMapValue(baseParamsMap, "ts"));
        //获取当前时间戳 并转化为秒
        callbackMap.put("ts", (System.currentTimeMillis()/1000)+"");





        List<String> tempList = new ArrayList<>();
        for(String key: callbackMap.keySet()){
            tempList.add(key+"="+callbackMap.get(key));
        }
        String callbackParams = String.join("&", tempList);
        String md5 = DigestUtils.md5DigestAsHex((callbackParams+callbackSecretkey).getBytes(Constants.UTF8)).toUpperCase();

        EncrypDES encrypDES = new EncrypDES();
        String callbackBase = OtherUtils.getServerUrl(request) + "ownJSApi/callback/"+channelId+"/"+dmpid+"/";
        String encrypt_u = encrypDES.encrypt(CALLBACK_URLBASE);
        String nu = callbackBase + encrypt_u + "?"+callbackParams+"&sign="+md5;

        baseParamsMap.put("ts", baseParamsMap.get("ts")+"000");
        baseParamsMap.put("callback_url", URLEncoder.encode(nu, Constants.UTF8));


        try {
            sendOcpxRequest(request, dmpid, baseParamsMap, channelDetail, callbackMap);
        }catch (Exception e){
            System.out.println("ocpx请求失败");
        }
        if("0".equals(channelDetail.get("isopen")+"")){
            return R.failure().msg("channelId未开启");
        }

        tempList = new ArrayList<>();
        for(String key: baseParamsMap.keySet()){
            tempList.add(key+"="+baseParamsMap.get(key));
        }
        String requestParameters = String.join("&", tempList);
        String reportResultsStr = "";
        if("POST".equals(requestType)){
            reportResultsStr = HttpUtils.sendPost(requestAddress, requestParameters, ip, ua);
        }else{
            reportResultsStr = HttpUtils.sendGet(requestAddress, requestParameters, ip, ua);
        }

        JSONObject reportResults = null;
        try {
            reportResults = JSONObject.parseObject(reportResultsStr);
            return reportResults==null?"":reportResults;
        }catch (Exception e){
            e.printStackTrace();
        }
        return reportResultsStr;
    }

    //获取ocpx回调地址
    private  String getOcpxCallback(HttpServletRequest request, String channelId,  String dmpid, String callbackClientId, String callbackSecretkey, LinkedHashMap<String, String> callbackMap) throws Exception {


        callbackMap.put("clientid", callbackClientId);
        List<String> tempList = new ArrayList<>();
        for(String key: callbackMap.keySet()){
            tempList.add(key+"="+ callbackMap.get(key));
        }
        String callbackParams = String.join("&", tempList);
        String md5 = DigestUtils.md5DigestAsHex((callbackParams+callbackSecretkey).getBytes(Constants.UTF8)).toUpperCase();

        EncrypDES encrypDES = new EncrypDES();
        String callbackBase = OtherUtils.getServerUrl(request) + "ownJSApi/ownOCPXApi/"+channelId+"/"+ dmpid +"/";
        String encrypt_u = encrypDES.encrypt(CALLBACK_URLBASE);
        String nu = callbackBase + encrypt_u + "?"+callbackParams+"&sign="+md5;
        return nu;
    }

    public static void main(String[] args) {
        System.out.println(System.currentTimeMillis()/1000);
    }

    //    发送ocpx请求
    @Async
    public void sendOcpxRequest(HttpServletRequest request, String dmpid, Map<String, Object> baseParamsMap, Map<String, Object> channelDetail,  LinkedHashMap<String, String> callbackMap) throws Exception {
        if(!channelDetail.containsKey(OP_CLASSESEN) && channelDetail.get(OP_CLASSESEN) == null){
            return;
        }
        List<Map<String, Object>> opChannelDetail = (List<Map<String, Object>>) channelDetail.get(OP_CLASSESEN);
        Map<String, Object> ocpxMap = null;
        for (Map<String, Object> stringObjectMap : opChannelDetail) {
            String opChannelId = stringObjectMap.get("id") + "";
            String callbackClientId = stringObjectMap.get("callback_clientid") + "";
            String callbackSecretkey = stringObjectMap.get("callback_secretkey") + "";
            String ocpxCallback = getOcpxCallback(request, opChannelId, dmpid, callbackClientId, callbackSecretkey, callbackMap);
            ocpxMap = new HashMap<>();
            ocpxMap.put("channelId", opChannelId);
            ocpxMap.put("dmpid", dmpid);
            ocpxMap.put("idfa", getMapValue(baseParamsMap, "idfa"));
            ocpxMap.put("imei_md5", getMapValue(baseParamsMap, "imei_md5"));
            ocpxMap.put("imei", getMapValue(baseParamsMap, "imei"));
            ocpxMap.put("mac_md5", getMapValue(baseParamsMap, "mac_md5"));
            String androidIdMd5 = getMapValue(baseParamsMap, "android_id_md5");
            if ("null".equals(androidIdMd5)) androidIdMd5 = "";
            ocpxMap.put("android_id_md5", androidIdMd5);
            String oaid = getMapValue(baseParamsMap, "oaid");
            if("null".equals(oaid))oaid = "";
            ocpxMap.put("oaid", oaid);
            String oaidMd5 = getMapValue(baseParamsMap, "oaid_md5");
            if ("null".equals(oaidMd5)) oaidMd5 = "";
            ocpxMap.put("oaid_md5", oaidMd5);
            ocpxMap.put("ua", getMapValue(baseParamsMap, "ua"));
            ocpxMap.put("ip", getMapValue(baseParamsMap, "ip"));
            String ocpxURL = OtherUtils.getServerUrl(request) + "ownOCPXApi/send";
            List<String> tempList = new ArrayList<>();
            for(String key: ocpxMap.keySet()){
                tempList.add(key+"="+ocpxMap.get(key));
            }
            String ocpxParams = String.join("&", tempList);
            ocpxParams += "&callback_url="+ URLEncoder.encode(ocpxCallback);
            HttpUtils.sendGet(ocpxURL, ocpxParams);
        }

    }

    private String getMapValue(Map<String, Object> map, String key){
        if(map == null){
            return "";
        }
        if(map.get(key) == null){
            return "";
        }
        return map.get(key)+"";
    }


    @Log(title = "极速科技", businessType = BusinessType.CALLBACK, esIndex = "jisu_log", saveType = SaveType.ES)
    @RequestMapping("/callback/{channelId}/{dmpid}/{encryptedUrl}")
    public Object send(HttpServletRequest request, @PathVariable("encryptedUrl") String encryptedUrl) throws Exception {
        String queryString = request.getQueryString();
        EncrypDES encrypDES = new EncrypDES();
        String requestAddress = encrypDES.decrypt(encryptedUrl);
        String resultStr = HttpUtils.sendGet(requestAddress, queryString);
        try {
            JSONObject resultJson = JSON.parseObject(resultStr);
            return resultJson==null?"":resultJson;
        }catch (Exception e){
            e.printStackTrace();
        }
        return resultStr;
    }

}
